<template>
  <lay-card class="banner-component">
    <Repl
      :store="store"
      :editor="Monaco"
      layout="vertical"
      :style="{ height: BoxHeight }"
      :clear-console="false"
    />
  </lay-card>
</template>
<script lang="ts">
export default {
  name: "DcodeBanner",
};
</script>

<script lang="ts" setup>
import type { PropType } from "vue";
import { ref, onMounted } from "vue";
import { Repl, useStore, useVueImportMap } from "@vue/repl";
import Monaco from "@vue/repl/monaco-editor";

type BannerPosition = "'top'| 'bottom'";
interface BannerContent {
  template: string;
  js: string;
  css: string;
}
const props = defineProps({
  /**
   * 渲染位置
   */
  position: {
    type: String as PropType<BannerPosition>,
    default: "top",
  },
  /**
   * 方法id
   */
  methodId: {
    type: String,
    default: "",
  },
  /**
   * 渲染内容
   */
  content: {
    type: Object as PropType<BannerContent>,
    default: {},
  },
  // banner template
  template: {
    type: String,
    default: "",
  },
  // banner data
  bannerData: {
    type: Object,
    default: () => ({}),
  },
});

const BoxHeight = ref("0");

const { importMap: builtinImportMap, vueVersion } = useVueImportMap({
  runtimeDev:
    "https://cdn.jsdelivr.net/npm/vue@3.4.21/dist/vue.runtime.esm-browser.js",
  runtimeProd:
    "https://cdn.jsdelivr.net/npm/vue@3.4.21/dist/vue.runtime.esm-browser.prod.js",
  serverRenderer:
    "https://cdn.jsdelivr.net/npm/@vue/server-renderer@3.4.21/dist/server-renderer.esm-browser.js",
});

const store = useStore({
  builtinImportMap,
  vueVersion,
  outputMode: ref("preview"),
  showOutput: ref(true),
});

if (!store.getFiles()["src/CustomBanner.vue"]) {
  // 渲染banner
  store.addFile("src/CustomBanner.vue");
  store.setActive("src/CustomBanner.vue");
  store.activeFile.code = props.template.replace(/\\x3C/g, "<");

  store.setActive("src/App.vue");
  store.activeFile.code = `
    <script>
      import CustomBanner from './CustomBanner.vue'
      export default {
        data () {
          return {
            bannerData: ${JSON.stringify(props.bannerData, null, 2).replace(/['"]/g, "")}
          }
        },
        components: {
          CustomBanner
        }
      }
    <\/script>
    <template>
      <CustomBanner :bannerData="bannerData" />
    </template>
  `;
  // store.serialize()
}

onMounted(() => {
  const replIframe = document.querySelector("iframe") as HTMLIFrameElement;

  window.addEventListener(
    "message",
    function () {
      BoxHeight.value =
        (replIframe?.contentDocument
          ?.querySelector("html")
          ?.getBoundingClientRect()?.height || 0) + "px";
    },
    false,
  );
});
</script>

<style lang="less" scoped>
.banner-component {
  padding-left: 20px;
  :deep(.vue-repl) {
    .left {
      display: none;
    }
    .right {
      width: 100% !important;
      height: 100% !important;
      .tab-buttons {
        display: none;
      }
      .output-container {
        height: 100%;
      }
      .msg {
        pre {
          width: 90%;
        }
      }
    }
    .toggler {
      display: none;
    }
  }
}
</style>
